define([
    'angular-loading-bar',
    'ng-file-upload-shim'
], function() {
    var utilFactory = angular.module('app.factory.util', ['angular-loading-bar', 'ngFileUpload']);

    utilFactory.factory('xUtil', ['$q', 'Upload', 'cfpLoadingBar', '$cookies', function($q, Upload, cfpLoadingBar,
            $cookies) {
        return {
            regex: {
                subMatch: function(text, regex) {
                    var match = regex.exec(text);
                    if (match != null && match.length >= 2) {
                        return match[1];
                    }
                    return '';
                },
                keyMatch: function(text, keyword) {
                    var rkeyword = new RegExp('^@' + keyword + '：(((?!\\n@)[^])*)\\n@', 'gmi');
                    return this.subMatch(text, rkeyword).trim();
                },
                urlMatch: function(text, path) {
                    var url = this.subMatch(text, /^@URL：(.*)/gmi).trim();
                    if (url == '') {
                        var dotIndex = path.lastIndexOf('.');
                        if (dotIndex > 0) {
                            path = path.substring(0, dotIndex);
                        }
                        url = '/' + path.replace(/\w+\//, '');
                    }
                    return url;
                }
            },
            file: {
                open: function(file) {
                    var defer = $q.defer();

                    // open file
                    Upload.upload({
                        url: '/mock/file/read',
                        method: 'POST',
                        data: {
                            'Content-Type': (file.type != '' ? file.type : 'application/octet-stream'),
                            'filename': file.name,
                            'file': file
                        }
                    }).then(function(response) {
                        defer.resolve(response.data);
                    }, function(data) {
                        defer.reject(data);
                    });

                    return defer.promise;
                },
                save: function(filename, content) {
                    var jqTargetId = 'jqFormIO-' + (new Date().getTime());

                    var jqForm = jQuery('<form style="display:none">').attr({
                            method: 'POST',
                            action: '/mock/file/write',
                            target: jqTargetId
                        }).appendTo(document.body);

                    var jqIframe = jQuery('<iframe style="display:none">').attr({
                            name: jqTargetId
                        }).appendTo(document.body);

                    // form data
                    jqForm.append(jQuery('<input type="hidden">').attr('name', 'filename').val(filename));
                    jqForm.append(jQuery('<textarea>').attr('name', 'content').val(content));

                    // submit
                    cfpLoadingBar.start();
                    jqForm.submit();

                    // remove
                    setTimeout(function() {
                        jqForm.remove();
                        jqIframe.remove();
                        cfpLoadingBar.complete();
                    }, 5000);
                }
            },
            image: {
                upload: function(file) {
                    var defer = $q.defer();

                    // upload image
                    Upload.upload({
                        url: '/mock/blog/upload',
                        method: 'POST',
                        data: {
                            'Content-Type': (file.type != '' ? file.type : 'application/octet-stream'),
                            'filename': file.name,
                            'file': file
                        }
                    }).then(function(response) {
                        defer.resolve(response.data);
                    }, function(data) {
                        defer.reject(data);
                    });

                    return defer.promise;
                }
            },
            host: {
                get: function() {
                    return this.list()[0];
                },
                list: function() {
                    var hosts = $cookies.get('test_hosts');
                    if (_.isEmpty(hosts)) {
                        return ['http://127.0.0.1:8080'];
                    } else {
                        return JSON.parse(hosts);
                    }
                },
                store: function(hosts) {
                    hosts = hosts || [];
                    $cookies.put('test_hosts', JSON.stringify(hosts));
                }
            }
        }
    }]);

    return utilFactory;
});
